<!DOCTYPE html>
<html>
<head>
  <title>Anime states system | anime.js</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:title" content="anime.js">
  <meta property="og:url" content="https://animejs.com">
  <meta property="og:description" content="Javascript Animation Engine">
  <meta property="og:image" content="https://animejs.com/documentation/assets/img/icons/og.png">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="anime.js">
  <meta name="twitter:site" content="@juliangarnier">
  <meta name="twitter:description" content="Javascript Animation Engine">
  <meta name="twitter:image" content="https://animejs.com/documentation/assets/img/icons/twitter.png">
  <link rel="apple-touch-icon-precomposed" href="../assets/img/social-media-image.png">
  <link rel="icon" type="image/png" href="../assets/img/favicon.png" >
  <link href="../assets/css/animejs.css" rel="stylesheet">
  <link href="../assets/css/documentation.css" rel="stylesheet">
  <style>

    body {
      display: flex;
      flex-wrap: no-wrap;
      justify-content: space-around;
      align-items: center;
      position: absolute;
      width: 100%;
      height: 100vh;
      padding-bottom: 128px;
    }

    .el {
      width: 50px;
      height: 50px;
      background-color: currentColor;
    }

    .log {
      overflow-y: scroll;
      position: absolute;
      top: 0;
      height: 100%;
      padding: 20px;
      padding-top: 80px;
      font-size: 16px;
      line-height: 20px;
      text-align: left;
      font-family: monospace;
    }

    .log-animation {
      left: 0;
      width: 50%;
    }

    .log-timeline {
      left: 50%;
      width: 50%;
    }

    .counter {
      display: inline-block;
      margin-right: 10px;
      padding: 3px;
      background-color: rgba(255,255,255,.2);
    }

    .currentTime, .progress { opacity: .5 }

    .time {
      position: absolute;
      top: 0;
      height: 80px;
      padding: 20px;
      font-size: 16px;
      line-height: 20px;
      text-align: left;
      font-family: monospace;
    }

    .time-animation {
      left: 0;
      width: 50%;
    }

    .time-timeline {
      left: 50%;
      width: 50%;
    }

    /* Player animation */

    .timeline {
      position: fixed;
      bottom: 0;
      height: 128px;
      padding-top: 4px;
      background-color: #000;
    }

    .timeline.player-animation {
      width: 50%;
      left: 0;
    }

    .timeline.player-timeline {
      width: 50%;
      left: 50%;
    }

    .tl-needle {
      position: absolute;
      z-index: 2;
      top: 0;
      left: 0;
      bottom: 0;
      width: 2px;
      margin-left: -1px;
      background-color: #FFF;
    }

    .tl-animation {
      position: relative;
      display: flex;
      justify-content: space-between;
      width: auto;
      height: 8px;
      margin-bottom: 4px;
      background-color: currentColor;
      border-radius: .5rem;
    }

    .tl-delay,
    .tl-end-delay {
      width: auto;
      height: 100%;
      background-color: rgba(0,0,0,.5);
    }

  </style>
</head>
<body>

  <div class="el color-04"></div>

  <div class="el color-08"></div>

  <div class="log log-animation"></div>
  <div class="time time-animation"></div>

  <div class="log log-timeline"></div>
  <div class="time time-timeline"></div>

</body>
<script type="module">

  import anime from '../../src/index.js';

  var animationTimeLogEl = document.querySelector('.time-animation');
  var timelineTimeLogEl = document.querySelector('.time-timeline');

  var animation = anime({
    targets: '.el.color-04',
    translateX: [
      {value: 200},
      {value: -200},
      {value: 200}
    ],
    rotate: {
      value: 720,
      easing: 'easeInOutCirc',
      duration: 500,
      delay: 500
    },
    opacity: {
      value: .5,
      easing: 'linear',
      duration: 1000,
      delay: 1000,
      endDelay: 0
    },
    delay: 1000,
    endDelay: 500,
    duration: 1000,
    easing: 'easeOutQuad',
    direction: 'reverse',
    loop: 2,
    autoplay: false,
    update: function(a) {
      animationTimeLogEl.innerHTML = 'progress : ' + a.progress + '<br>currentTime : ' + a.currentTime;
    },
  });


  var tl = anime.timeline({
    targets: '.el.color-08',
    easing: 'easeInOutQuad',
    autoplay: false,
    direction: 'alternate',
    loop: 3,
    update: function(a) {
      timelineTimeLogEl.innerHTML = 'progress : ' + a.progress + '<br>currentTime : ' + a.currentTime;
    }
  })
  .add({
    translateX: 100,
    delay: 1000
  })
  .add({
    translateY: 100
  }, '-=500')
  .add({
    rotate: 360,
    endDelay: 1000
  }, '-=500');


  function animePlayer(instance, playerClass) {

    function createEl(type, className, parentEl) {
      var el = document.createElement(type);
      if (className) el.classList.add(className);
      if (parentEl) parentEl.appendChild(el);
      return el;
    }

    var timelineEl = createEl('div', 'timeline', document.body);
    if (playerClass) timelineEl.classList.add(playerClass);
    var needleEl = createEl('div', 'tl-needle', timelineEl);
    var animations = [];
    var colors = ['#FF1461','#FF7C72','#FBF38C','#A6FF8F','#18FF92','#1CE2B2','#5EF3FB','#61C3FF','#5A87FF','#8453E3','#C26EFF','#FB89FB'];
    var colorIndex = 0;

    function convertMStoEM(ms) { return ms / 100; }
    function convertEMtoMS(em) { return parseFloat(em) * 250; }

    function createAnimationLog(animObj, timelineOffset) {
      var anim = animObj;
      anim.player = {};
      anim.player.animationEl = createEl('div', 'tl-animation', timelineEl);
      anim.player.delayEl = createEl('div', 'tl-delay', anim.player.animationEl);
      anim.player.endDelayEl = createEl('div', 'tl-end-delay', anim.player.animationEl);
      anim.update = function() {
        anime.set(anim.player.animationEl, {
          left: convertMStoEM(timelineOffset) + 'em',
          width: convertMStoEM(anim.duration) + 'em'
        });
        anime.set(anim.player.delayEl, {width: (anim.delay / anim.duration) * 100 + '%'});
        anime.set(anim.player.endDelayEl, {width: (anim.endDelay / anim.duration) * 100 + '%'});
      }
      anime.set(anim.player.animationEl, {color: colors[colorIndex]});
      colorIndex++;
      if (!colors[colorIndex]) colorIndex = 0;
      anim.update();
      animations.push(anim);
      return anim;
    }

    instance.pause();

    var playerAnimation = anime({
      targets: needleEl,
      translateX: convertMStoEM(instance.duration) + 'em',
      duration: instance.duration,
      direction: instance.direction,
      loop: instance.loop,
      easing: 'linear',
      update: function(a) {
        instance.seek(a.currentTime);
      },
      complete: function(a) {
        instance.seek(a.currentTime);
      }
    });

    if (instance.children.length) {
      instance.children.forEach(function(child) {
        child.animations.forEach(function(anim) {
          createAnimationLog(anim, child.timelineOffset);
        });
      })
    } else {
      instance.animations.forEach(function(anim) {
        createAnimationLog(anim);
      });
    }

  }

  animePlayer(animation, 'player-animation');
  animePlayer(tl, 'player-timeline');

  function logCallbacks(animation, logEl, callbacks) {

    function appendLog(cbName) {
      animation[cbName] = function() {
        var pEl = document.createElement('p');
        var counterSpanEl = document.createElement('span');
        var currentTimeSpanEl = document.createElement('span');
        var progressSpanEl = document.createElement('span');
        var textSpanEl = document.createElement('span');
        var lastPEl = logEl.querySelector('p:last-child');
        currentTimeSpanEl.innerHTML = ' ' + animation.currentTime + 'ms';
        progressSpanEl.innerHTML = ' ' + animation.progress + '%';
        if (lastPEl && lastPEl.querySelector('.text').innerHTML === cbName) {
          var lastCountEl = lastPEl.querySelector('.counter');
          var lastCountValue = parseFloat(lastCountEl.innerHTML);
          lastCountValue++;
          lastCountEl.innerHTML = lastCountValue;
        } else {
          counterSpanEl.innerHTML = 1;
          textSpanEl.innerHTML = cbName;
          counterSpanEl.classList.add('counter');
          textSpanEl.classList.add('text');
          currentTimeSpanEl.classList.add('currentTime');
          progressSpanEl.classList.add('progress');
          pEl.appendChild(counterSpanEl);
          pEl.appendChild(textSpanEl);
          pEl.appendChild(currentTimeSpanEl);
          pEl.appendChild(progressSpanEl);
          logEl.appendChild(pEl);
          logEl.scrollTop = logEl.scrollHeight;
        }
      }
    }

    callbacks.forEach(appendLog);

  }

  logCallbacks(animation, document.querySelector('.log-animation'), [
    'begin',
    'loopBegin',
    'changeBegin',
    'change',
    'changeComplete',
    'loopComplete',
    'complete'
  ]);


  logCallbacks(tl, document.querySelector('.log-timeline'), ['begin',
    'loopBegin',
    'changeBegin',
    'change',
    'changeComplete',
    'loopComplete',
    'complete'
  ]);


</script>
</html>
